/*******************************************************************************
 * Copyright 2011 Towee.net
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package net.towee.client.widgets.tree;

import java.util.ArrayList;
import java.util.List;

import net.towee.client.widgets.ListItemWidget;
import net.towee.client.widgets.SpanPanel;
import net.towee.client.widgets.UnorderedListWidget;

import com.google.gwt.event.logical.shared.HasOpenHandlers;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;

public class Tree<T> extends UnorderedListWidget implements HasOpenHandlers<T>, HasSelectionHandlers<T> {
	protected FlowPanel content = new FlowPanel();
	protected ListItemWidget list = new ListItemWidget();
	protected UnorderedListWidget container = new UnorderedListWidget();
	
	protected List<TreeItem> children = new ArrayList<TreeItem>();
	protected List<TreeItem> selected = new ArrayList<TreeItem>();
	protected List<TreeItem> opened = new ArrayList<TreeItem>();

	public Tree() {
		this(null);
	}
	public Tree(String name){
		// Set styles
		this.setStyleName("tn-container");
		list.setStyleName("tn-node");
		list.addStyleName("tn-opened");
		list.addStyleName("tn-root");
		container.setStyleName("tn-container");
		content.setStyleName("tn-content");
		content.addStyleName("tn-root");
		
		// Make ui
		list.add(content);
		list.add(container);
		add(list);
		
		if(name != null)
			setContent(name);
	}
	
	public void setContent(Widget c){
		content.add(c);
	}
	
	public void setContent(String c){
		content.add(new SpanPanel(c));
	}
	
	public void addChildNode(TreeItem node){
		node.setRoot(this);
		container.add(node);
		children.add(node);
	}
	
	public void closeAll(){
		for(TreeItem node : children){
			node.closeAll(true);
		}
	}

	public void unselectNodes() {
		for(TreeItem node : selected) {
			node.setSelectState(false, true);
		}
		
		selected.clear();
	}

	public void addSelectedNode(TreeItem treeNode, boolean ctrlDown, boolean fire) {
		selected.add(treeNode);
		
		if(ctrlDown == false && fire == true)
			SelectionEvent.fire(this, (T)treeNode.getLayoutData());
	}

	public void removeSelectedNode(TreeItem treeNode) {
		selected.remove(treeNode);
	}

	public void nodeOpened(TreeItem treeNode) {
		opened.add(treeNode);
		OpenEvent.fire(this, (T)treeNode.getLayoutData());
	}
	
	public List<TreeItem> getSelectedNodes(){
		return selected;
	}

	public void nodeClosed(TreeItem treeNode) {
		opened.remove(treeNode);
	}
	
	@Override
	public HandlerRegistration addSelectionHandler(SelectionHandler<T> handler) {
		return addHandler(handler, SelectionEvent.getType());
	}
	
	@Override
	public HandlerRegistration addOpenHandler(OpenHandler<T> handler) {
		return addHandler(handler, OpenEvent.getType());
	}
}
